#include "Validator.h";

//these are the few keywords that will be mostly used. can add more
const string Validator::keywordArray[]= { "DATE", "STARTS", "ENDS", "PLACE"};
// 5 for now. 
const int Validator::max_size = 4;

bool Validator::isValidCommand(string command){
        command= toLowerCase(command);
        if(command == "add" || command =="delete" || command== "show"||command== "edit"
                || command== "search"||command== "clear" ||command=="done"
                ||command== "carry forward"||command== "undo"||command=="help" 
                ||command== "exit")
                return true;
        else
                return false;

};

bool Validator::isEmptyString(string sentence){
        if(sentence.size()==0)
                return true;
        else 
                return false;
};

bool Validator::isEmptyTaskList(vector<Task*> & taskList){
        if(taskList.size()==0)
                return true;
        else
                return false;
};
//the function checks if every character if its a digit
// its assumed that any input with everycharacter is a digit, that input is cosidered an integer. 
//else it is a string.
bool Validator::isInt(string input){
        int check =0;
        for(int i=0; i < input.size(); i ++){
        if(isdigit(input[i]))
                check +=1;
        }
        if(check== input.size())
                return true;
        else 
                return false;
};

bool Validator::isLeapYear(string year){
	int leapyear;
	leapyear= atoi(year.c_str());

        if(!(leapyear%4) && (leapyear%100) || !(leapyear%400))
                return true;
        else
                return false;

};

bool Validator::isValidDate(string date){
		date=makeProperDateFormat(date);
        tokenizeDate(date);
        changeStringToInt();
        int day= getDay();
        int month= getMonth();
        string year= getYear();
        if((isValidDay(day,month, year)) && (isValidMonth(day,month,year)) && (isValidYear(year))){
			dateVector.erase(dateVector.begin(), dateVector.end());
                return true;
		}
        else{
			dateVector.erase(dateVector.begin(), dateVector.end());
            return false;
		}
};

bool Validator::isValidKeyword(string word){
        for(int i=0; i < max_size; i++){
                if(word == keywordArray[i])
                        return true;
        }

        return false;
};

// vector is used as there maybe more than 1 occurance of the same taskname in the storage.
bool Validator::isValidTask(string taskname, vector<Task*> & taskList){
        for(int i =0; i < taskList.size(); i ++){
                if (taskname == taskList[i]->getName())
                        tempVector.push_back(taskname);
        }
                if (!tempVector.empty())
                        return true;
                else 
                        return false;
                tempVector.erase(tempVector.begin(), tempVector.end());

        
};

bool Validator::isValidTaskNumber(int tasknumber, vector<Task*> & taskList){
// still figuring it out :( sorry

        return true;
};


string Validator::toLowerCase(string command){
        for(int i=0; i< command.size(); i++){
                command[i]=tolower(command[i]);
        }

        return command;
};

int Validator::getDay(){
        int day = dateVector[0];
        return day;
};

int Validator::getMonth(){
        int month = dateVector[1];
        return month;
};

string Validator::getYear(){
        string year= tempVector[2];
		tempVector.erase(tempVector.begin(),tempVector.end());
        return year;
};

bool Validator::isValidDay(int day, int month,string year){
        if(day != 0 &&  isValidMonth(day, month,year))
                return true;
        else 
                return false;
        

};

bool Validator::isValidMonth(int day, int month, string year){
        switch (month){
        case 1:
        case 3:
        case 5:
        case 7:
        case 8:
        case 10:
        case 12:
                
                if(day <= 31)
					return true;
				else
					return false;
				break;
        
        case 2:{
        
                if(isLeapYear(year)){
					if(day<= 29)
                        return true;
					else 
						return false;   
                }
                else{
                       if( day <= 28)
                        return true;
					   else
						   return false;
                }
                break;
			   }        
        case 4:
        case 6:
        case 9:
        case 11:
               
               if( day <= 30)
				   return true;
			   else
				   return false;
               break;
                
        default:
                return false;

        }
};

bool Validator::isValidYear(string year){
	int check=0;
	for(int i=0; i<year.size(); i ++){
        if(isdigit(year[i]))
			check+=1;
	}
	if(check== year.size())
		return true;
	else 
		return false;

      
};

// the date comes in the form of a string
// this hels to spilt the date into day, month and year.
void Validator::tokenizeDate(string date){
        istringstream tokenizethedate(date);
        string token;
        while(!tokenizethedate.eof()){
                getline(tokenizethedate, token,'/');
                tempVector.push_back(token);
        }
        
};

// this function converts the  split string date into integers
void Validator::changeStringToInt(){

for(int i=0; i < tempVector.size()-1; i++){
        string convertstring = tempVector[i];
        int converted = atoi(convertstring.c_str());
        dateVector.push_back(converted);
}

};
 bool Validator::isValidTaskName(string taskname){
	 int check=0;
	 for(int i=0; i<taskname.size(); i++){
		 if(isalpha(taskname[i])||isdigit(taskname[i]))
			check+=1;
		 else 
			 check=0;
 }
	 if(check!= 0)
		 return true;
	 else
		 return false;
 };

 string Validator::makeProperDateFormat(string date){
	 string newdate;
	 int slash=0;
	 for(int i=0; i <date.size(); i++){
		 if(date[i]=='/')
			 slash+= 1;
		 else
			 slash+= 0;
	 }

	 if(slash==2)
		 return date;
	 if(slash==0){
		newdate= addMonthAndYear(date);
		 return newdate;
	 }
	 if(slash==1){
		 newdate=addYear(date);
		 return newdate;
	 }


 };

 //tm_mon tells you the month from 0:Jan to 11:Dec
string Validator::addMonthAndYear(string date){
	 string monthtobeadded;
	 stringstream ss;
	 time_t rawtime;
	 struct tm * timeinfo;
	 int currentmonth;

	time ( &rawtime );
	timeinfo = localtime ( &rawtime );
	currentmonth= timeinfo->tm_mon + 1;
	ss<< currentmonth;
	monthtobeadded= ss.str();
	date=date.append("/");
	date=date.append(monthtobeadded);
	date=addYear(date);
	return date;

 };

//tm_year gives u the number of years since 1900
 string Validator::addYear(string date){
	 string yeartobeadded;
	 stringstream ss;
	 time_t rawtime;
	 struct tm * timeinfo;
	 int currentmonth;

	time ( &rawtime );
	timeinfo = localtime ( &rawtime );
	currentmonth= timeinfo->tm_year + 1900;
	ss<< currentmonth;
	yeartobeadded= ss.str();
	date=date.append("/");
	date=date.append(yeartobeadded);

	 return date;
 };

 bool Validator::isValidTaskTime(int start_time, int end_time){
	 time_t rawtime;
	 struct tm * timeinfo;
	 int current_time;
	 time ( &rawtime );
	 timeinfo = localtime ( &rawtime );
	 current_time= timeinfo->tm_hour +1;
	 if(((current_time>= start_time)  || (current_time >= end_time)) && (end_time > start_time))
		 return true;
	 else
		 return false;
 };